package com.cyrusInnovation.test;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.cyrusInnovation.test.formatter.PersonRecordFormatter;
import com.cyrusInnovation.test.record.PersonRecord;

public class PersonRecordURLReader {

	private URL recordURL;

	private PersonRecordFormatter recordFormatter;

	private List<PersonRecord> records = new ArrayList<PersonRecord>();

	private boolean isRead = false;

	public PersonRecordURLReader() {
	}

	public PersonRecordURLReader(URL recordURL,
			PersonRecordFormatter recordFormatter) {
		setRecordURL(recordURL);
		setRecordFormatter(recordFormatter);
	}

	public void setRecordURL(URL recordURL) {
		this.recordURL = recordURL;
		refresh();
	}

	public void setRecordFormatter(PersonRecordFormatter recordFormatter) {
		this.recordFormatter = recordFormatter;
		refresh();
	}

	protected void setRead(boolean isRead) {
		this.isRead = isRead;
	}

	protected URL getRecordURL() {
		return recordURL;
	}

	private PersonRecordFormatter getRecordFormatter() {
		return recordFormatter;
	}

	private LineNumberReader getLineReader() {
		return getURLLineReader(getRecordURL());
	}

	private boolean readFromFile() throws IOException {
		if (isRead) {
			return true;
		}

		records.clear();

		if (getRecordFormatter() == null) {
			return false;
		}

		LineNumberReader lnReader = getLineReader();
		if (lnReader == null) {
			throw new IOException("Fail to obtain line reader for "
					+ recordURL.toString());
		}

		for (String line = lnReader.readLine(); line != null; line = lnReader
				.readLine()) {
			if (line.length() > 1) {
				records.add(recordFormatter.StringToPersonRecord(line));
			}
		}
		lnReader.close();

		setRead(true);
		return true;
	}

	public List<PersonRecord> getRecords() throws IOException {
		readFromFile();
		return records;
	}

	public void refresh() {
		setRead(false);
		records.clear();
	}

	public static LineNumberReader getURLLineReader(URL url) {
		LineNumberReader lnReader;
		if (url == null) {
			return null;
		}
		try {
			lnReader = new LineNumberReader(new InputStreamReader(url
					.openStream()));
		} catch (Exception e) {
			return null;
		}
		return lnReader;
	}

}
